#include "chitu_base.h"

static int chitu_array_size = sizeof(chitu_array);
//static int chitu_matrix_size = sizeof(chitu_matrix);

#define malloc_array() malloc(chitu_array_size)
//#define malloc_matrix() malloc(chitu_matrix_size)

//数组的创建和操作
chitu_array *chitu_array_create(uint64_t len, double init)
{
    chitu_array *newa = malloc_array();
    
    if (len <= 0)
    {
        newa->val = NULL;
        newa->length = 0;
    }
    else
    {
        newa->val = malloc(sizeof(double) * len);
        newa->length = len;

        for (uint64_t i = 0; i < len; i++)
            newa->val[i] = init;
    }

    return newa;
}

void chitu_array_free(chitu_array *a)
{
    if (a->val != NULL)
        free(a->val);
    a->val = NULL;
    a->length = 0;
    free(a);
}

inline void *chitu_array_dataptr(chitu_array *a)
{
    return a != NULL ? a->val : NULL;
}

void chitu_array_clear(chitu_array *a)
{
    
    if (a->val != NULL)
        free(a->val);
    a->val = NULL;
    a->length = 0;
}

inline uint64_t chitu_array_length(chitu_array *a)
{
    return a->length;
}

inline bool chitu_array_get(chitu_array *a, uint64_t index, double *data)
{
    uint64_t len = a->length;
    if (index <0 || index >= len)
        return false;
    *data = a->val[index];
    return true;
}

inline bool chitu_array_insert(chitu_array *a, uint64_t index, double data)
{
    uint64_t len = a->length;
    if (index <0 || index >= len)
        return false;
    a->val[index] = data;
    return true;
}

void chitu_array_set(chitu_array *a, double n)
{
    for (uint64_t i = 0; i < a->length; i++)
        a->val[i] += n;
}

void *chitu_array_cat(chitu_array *a, chitu_array *b)
{
    uint64_t i = 0;
    chitu_array *newa = malloc_array();
    newa->length = a->length + b->length;
    newa->val = malloc(sizeof(double) * newa->length);

    for (; i < a->length; i++)
        newa->val[i] = a->val[i];
    
    for (; i < newa->length; i++)
        newa->val[i] = b->val[i - a->length];
    
    return newa;
}

void chitu_array_print(chitu_array *a)
{
    for (uint64_t i = 0; i < a->length; i++)
    {
        if (i % 5 == 0 && i != 0)
            putchar('\n');
        printf("%.8f ", a->val[i]);
    }
    putchar('\n');
}

void *chitu_array_copy(chitu_array *a)
{
    chitu_array *newa = malloc_array();
    newa->length = a->length;
    newa->val = malloc(sizeof(double) * newa->length);

    for (uint64_t i = 0; i < newa->length; i++)
        newa->val[i] = a->val[i];
    
    return newa;
}

void *chitu_array_slice(chitu_array *a, uint64_t start, uint64_t end)
{
    if (end <= start || start <0 || end >= a->length)
        return chitu_array_create(0, 0);
    
    chitu_array *newa = malloc_array();
    newa->length = end - start;
    newa->val = malloc(sizeof(double) * newa->length);

    for (uint64_t i = start; i < end; i++)
        newa->val[i - start] = a->val[i];
    
    return newa;
}

void chitu_array_cfunct(chitu_array *a, double ( *cfunct)(double))
{
    for (uint64_t i = 0; i < a->length; i++)
        a->val[i] = cfunct(a->val[i]);
}

